home *** CD-ROM | disk | FTP | other *** search
/ T&A 2 the Maxx 3 / T and A 2 The Maxx Number 3.iso / viewers / unixview / xgl17dta.z / xgl17dta / glib.c < prev    next >
C/C++ Source or Header  |  1991-07-24  |  8KB  |  361 lines

  1. #ident "@(#)glib.c    1.5 91/04/01 XGRASP"
  2. /*-
  3.  * glib.c - GRASP graphics librarian.
  4.  *
  5.  * Copyright (c) 1991 by Patrick J. Naughton
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both that copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * This file is provided AS IS with no warranties of any kind.  The author
  14.  * shall have no liability with respect to the infringement of copyrights,
  15.  * trade secrets or any patents by this file or any part thereof.  In no
  16.  * event will the author be liable for any lost revenue or profits or
  17.  * other special, indirect and consequential damages.
  18.  *
  19.  * Comments and additions should be sent to the author:
  20.  *
  21.  *                     Patrick J. Naughton
  22.  *                     Sun Microsystems
  23.  *                     2550 Garcia Ave, MS 10-20
  24.  *                     Mountain View, CA 94043
  25.  *                     (415) 336-1080
  26.  *
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31.  
  32. char       *pname;
  33. extern char *strrchr();
  34.  
  35. typedef struct {
  36.     char        fname[14];
  37.     long        offset;
  38.     long        len;
  39.     char       *data;
  40. }           FilenameStruct;
  41.  
  42. void
  43. error(s1, s2, s3)
  44.     char       *s1, *s2, *s3;
  45. {
  46.     fprintf(stderr, s1, pname, s2, s3);
  47.     exit(1);
  48. }
  49.  
  50. u_int
  51. GetWord(fp)
  52.     FILE       *fp;
  53. {
  54.     u_char      b1 = (u_char) getc(fp);
  55.     u_char      b2 = (u_char) getc(fp);
  56.  
  57.     return (u_int) (b1 + b2 * 256);
  58. }
  59.  
  60. u_int
  61. GetLong(fp)
  62.     FILE       *fp;
  63. {
  64.     u_char      b1 = (u_char) getc(fp);
  65.     u_char      b2 = (u_char) getc(fp);
  66.     u_char      b3 = (u_char) getc(fp);
  67.     u_char      b4 = (u_char) getc(fp);
  68.     return (u_int) (b1 + b2 * 256 + b3 * 256 * 256 + b4 * 256 * 256 * 256);
  69. }
  70.  
  71. void
  72. PutWord(fp, w)
  73.     FILE       *fp;
  74.     unsigned int w;
  75. {
  76.     unsigned char b1 = w & 255;
  77.     unsigned char b2 = (w >> 8) & 255;
  78.     putc(b1, fp);
  79.     putc(b2, fp);
  80. }
  81.  
  82. void
  83. PutLong(fp, l)
  84.     FILE       *fp;
  85.     unsigned int l;
  86. {
  87.     unsigned char b1 = l & 255;
  88.     unsigned char b2 = (l >> 8) & 255;
  89.     unsigned char b3 = (l >> 16) & 255;
  90.     unsigned char b4 = (l >> 24) & 255;
  91.  
  92.     putc(b1, fp);
  93.     putc(b2, fp);
  94.     putc(b3, fp);
  95.     putc(b4, fp);
  96. }
  97.  
  98. void
  99. extractfile(in, dir, i)
  100.     FILE       *in;
  101.     FilenameStruct *dir;
  102.     int         i;
  103. {
  104.     int         len;
  105.     char       *data;
  106.     FILE       *out;
  107.  
  108.     fseek(in, dir[i].offset, 0);
  109.     len = GetLong(in);
  110.     len &= 0x00ffffff;
  111.     data = (char *) malloc(len);
  112.     if (!data)
  113.     error("%s: not enough memory\n");
  114.     fread(data, len, 1, in);
  115.     out = fopen(dir[i].fname, "w");
  116.     if (!out)
  117.     error("%s: error writing: %s\n", dir[i].fname);
  118.     fwrite(data, len, 1, out);
  119.     fclose(out);
  120.     free(data);
  121. }
  122.  
  123. void
  124. writefile(fname, dir, nfiles)
  125.     char       *fname;
  126.     FilenameStruct *dir;
  127.     int         nfiles;
  128. {
  129.     FILE       *out;
  130.     int         i;
  131.     long        offset = 2 + (nfiles + 1) * (13 + 4);
  132.  
  133.     out = fopen(fname, "w");
  134.     PutWord(out, (nfiles + 1) * (13 + 4));
  135.     for (i = 0; i < nfiles; i++) {
  136.     PutLong(out, offset);
  137.     offset += dir[i].len + 4;
  138.     fwrite(dir[i].fname, 13, 1, out);
  139.     }
  140.     PutLong(out, 0);
  141.     fwrite("             ", 13, 1, out);
  142.     for (i = 0; i < nfiles; i++) {
  143.     PutLong(out, dir[i].len);
  144.     fwrite(dir[i].data, dir[i].len, 1, out);
  145.     }
  146.     fclose(out);
  147. }
  148.  
  149. int
  150. findname(dir, nfiles, s)
  151.     FilenameStruct *dir;
  152.     int         nfiles;
  153.     char       *s;
  154. {
  155.     int         i;
  156.  
  157.     if (dir)
  158.     for (i = 0; i < nfiles; i++)
  159.         if (!strcmp(dir[i].fname, s))
  160.         return i;
  161.     return -1;
  162. }
  163.  
  164.  
  165. usage()
  166. {
  167.     error("usage: %s [-dstuea] libname [files...]\n", NULL);
  168. }
  169.  
  170. main(argc, argv)
  171.     int         argc;
  172.     char       *argv[];
  173. {
  174.     int         i;
  175.     FILE       *in;
  176.     FILE       *out;
  177.     char       *libfname;
  178.     char       *opfname;
  179.     int         nfiles = 0;
  180.     FilenameStruct *dir = 0;
  181.     int         thefile = -1;
  182.     int         c;
  183.     int         dflg = 0;
  184.     int         sflg = 0;
  185.     int         tflg = 0;
  186.     int         uflg = 0;
  187.     int         eflg = 0;
  188.     int         aflg = 0;
  189.  
  190.     extern char *optarg;
  191.     extern int  optind;
  192.  
  193.     pname = argv[0];
  194.  
  195.     if (argc == 1)
  196.     usage();
  197.     while ((c = getopt(argc, argv, "hd:s:t:u:e:a:")) != -1)
  198.     switch (c) {
  199.     case 'h':
  200.         printf("\nusage: glib [-dstuea] libname [files...]\n");
  201.         printf("\n        where the following commands are supported:\n\n");
  202.         printf("\t-d   delete file from library\n");
  203.         printf("\t-s   extended file list\n");
  204.         printf("\t-t   quick file list\n");
  205.         printf("\t-u   update (add) file to library\n");
  206.         printf("\t-e   extract file from library\n");
  207.         printf("\t-a   extract all files from library\n\n");
  208.         exit(0);
  209.     case 'd':
  210.         if (uflg || eflg || aflg)
  211.         usage();
  212.         else
  213.         dflg++;
  214.         libfname = optarg;
  215.         break;
  216.     case 's':
  217.         if (tflg)
  218.         usage();
  219.         else
  220.         sflg++;
  221.         libfname = optarg;
  222.         break;
  223.     case 't':
  224.         if (sflg)
  225.         usage();
  226.         else
  227.         tflg++;
  228.         libfname = optarg;
  229.         break;
  230.     case 'u':
  231.         if (dflg || eflg || aflg)
  232.         usage();
  233.         else
  234.         uflg++;
  235.         libfname = optarg;
  236.         break;
  237.     case 'e':
  238.         if (dflg || uflg || aflg)
  239.         usage();
  240.         else
  241.         eflg++;
  242.         libfname = optarg;
  243.         break;
  244.     case 'a':
  245.         if (dflg || uflg || eflg)
  246.         usage();
  247.         else
  248.         aflg++;
  249.         libfname = optarg;
  250.         break;
  251.     default:
  252.         usage();
  253.     }
  254.  
  255.     if (!libfname)
  256.     usage();
  257.  
  258.     in = fopen(libfname, "r");
  259.     if (!in && !uflg)
  260.     error("%s: %s not found!\n", libfname);
  261.  
  262.     if (in) {
  263.     nfiles = (GetWord(in) / 17) - 1;
  264.     dir = (FilenameStruct *) malloc(nfiles * sizeof(FilenameStruct));
  265.     for (i = 0; i < nfiles; i++) {
  266.         dir[i].offset = GetLong(in);
  267.         fread(dir[i].fname, 13, 1, in);
  268.         dir[i].fname[13] = 0;
  269.         if (dflg || eflg) {
  270.         if (!strcmp(dir[i].fname, argv[optind]))
  271.             thefile = i;
  272.         }
  273.     }
  274.  
  275.     if ((dflg || eflg) && thefile == -1)
  276.         error("%s: %s not found in %s.\n", argv[optind], libfname);
  277.  
  278.     if (sflg || tflg || dflg || uflg) {
  279.         if (sflg)
  280.         printf("## filename.ext\toffset\tsize\n%s",
  281.                "-- ------------\t------\t----\n");
  282.         for (i = 0; i < nfiles; i++) {
  283.         fseek(in, dir[i].offset, 0);
  284.         dir[i].len = GetLong(in);
  285.         dir[i].len &= 0x00ffffff;
  286.         if (sflg)
  287.             printf("%2d %s\t%d\t%d\n",
  288.                i, dir[i].fname, dir[i].offset, dir[i].len);
  289.         else if (tflg)
  290.             printf("%s%c", dir[i].fname,
  291.                (i + 1) % 4 && i + 1 < nfiles ? '\t' : '\n');
  292.  
  293.         if (dflg || uflg) {
  294.             dir[i].data = (char *) malloc(dir[i].len);
  295.             if (!dir[i].data)
  296.             error("%s: not enough memory\n");
  297.             fread(dir[i].data, dir[i].len, 1, in);
  298.         }
  299.         }
  300.     }
  301.     }
  302.     if (eflg) {
  303.     extractfile(in, dir, thefile);
  304.     fclose(in);
  305.     } else if (aflg) {
  306.     for (i = 0; i < nfiles; i++)
  307.         extractfile(in, dir, i);
  308.     fclose(in);
  309.     } else if (dflg) {
  310.     fclose(in);
  311.     nfiles--;
  312.     for (i = thefile; i < nfiles; i++)
  313.         memcpy(&dir[i], &dir[i + 1], sizeof(FilenameStruct));
  314.     writefile(libfname, dir, nfiles);
  315.     } else if (uflg) {
  316.  
  317.     if (in)
  318.         fclose(in);
  319.     for (i = optind; i < argc; i++) {
  320.         char       *s = argv[i];
  321.         char       *fn = strrchr(s, '/');
  322.         int         n;
  323.         int         idx;
  324.  
  325.         fn = (fn == 0) ? s : fn + 1;
  326.         n = strlen(fn);
  327.         if (n > 13)
  328.         error("%s: '%s' is too long, must be < 13 chars.\n", s);
  329.  
  330.         idx = findname(dir, nfiles, fn);
  331.  
  332.         if (idx == -1) {
  333.         nfiles++;
  334.         if (!dir)
  335.             dir = (FilenameStruct *) malloc(sizeof(FilenameStruct));
  336.         else
  337.             dir = (FilenameStruct *) realloc(dir,
  338.                          nfiles * sizeof(FilenameStruct));
  339.         idx = nfiles - 1;
  340.         } else
  341.         free(dir[idx].data);
  342.         memset(dir[idx].fname, 0, 14);
  343.         memcpy(dir[idx].fname, fn, n);
  344.         in = fopen(s, "r");
  345.         if (!in)
  346.         error("%s: %s not found!\n", s);
  347.  
  348.         fseek(in, 0L, 2);    /* eof */
  349.         dir[idx].len = ftell(in);
  350.         fseek(in, 0L, 0);    /* bof */
  351.         dir[idx].data = (char *) malloc(dir[idx].len);
  352.         if (!dir[idx].data)
  353.         error("%s: not enough memory\n");
  354.         fread(dir[idx].data, dir[idx].len, 1, in);
  355.         fclose(in);
  356.     }
  357.     writefile(libfname, dir, nfiles);
  358.     }
  359.     exit(0);
  360. }
  361.